﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using TowerDefence.Entities.States;

namespace TowerDefence.Entities.Actions
{
    /// <summary>
    /// Shoots the UserEntity along a given vector,
    /// killing it after a set time (if the entity has an AliveState)    
    /// </summary>
    public class ShootAction : Action
    {        
        private TimeSpan timeToLive;
        private Vector2 vector;
        private int damage;
        private CollisionCircle userCircle;

        public ShootAction(            
            TimeSpan _timeToLive,
            Vector2 _vector,
            int _damage,
            Entity _userEntity,
            params Entity[] _targetEntities) 
            : base(_userEntity, _targetEntities) 
        {
            this.timeToLive = _timeToLive;
            this.vector = _vector;
            this.damage = _damage;
            this.userCircle = _userEntity.Form.States.GetState<CollisionCircle>();
        }

        public override void DoAction(TimeSpan _time)
        {
            CheckTime(_time);
            if (Active)
            {
                MoveUserEntity(_time);
                CheckCollision();
            }
        }

        /// <summary>
        /// Checks whether the shoot action should have expired
        /// Kills the userEntity when it has (if it has an AliveState)
        /// </summary>
        private void CheckTime(TimeSpan _time)
        {
            timeToLive -= _time;

            if (timeToLive.TotalSeconds <= 0)
            {
                this.Active = false;
                var aliveState = userEntity.Form.States.GetState<AliveState>();
                if (aliveState != null)
                {
                    aliveState.LifeState = eLifeState.Dead;
                }
            }
        }

        /// <summary>
        /// Movement is in units (i.e. pixels) per second
        /// TODO: Make this use the real Move action!
        /// </summary>
        private void MoveUserEntity(TimeSpan _time)
        {
            userEntity.Form.Position += this.vector * (float)_time.TotalSeconds;
        }

        /// <summary>
        /// Checks if the user and target entities collide
        /// Currently only works with CollisionCircles
        /// </summary>
        private void CheckCollision()
        {
            if (userCircle == null) return;
            
            foreach(var targetEntity in this.targetEntities)
            {
                var targetCircle = targetEntity.Form.States.GetState<CollisionCircle>();
                if(targetCircle == null) continue;
                targetCircle.Position = targetEntity.Form.Position;
                this.userCircle.Position = this.userEntity.Form.Position;
                if (!Collision.Collides(targetCircle, userCircle))
                {
                    continue;
                }                
                var targetHealth = targetEntity.Form.States.GetState<HealthState>();
                if (targetHealth == null) continue;
                targetHealth.Health -= this.damage;
                if (targetHealth.Health <= 0)
                {
                    targetEntity.AddAction(new DieAction(targetEntity, null));
                }
            }
        }
    }
}
